#!/usr/bin/env python

# (c) 2007-2011 Helsinki University of Technology and University of Helsinki
# Licensed under the MIT license; see LICENSE.txt for more information.

from harava.worker import Worker
from harava.document import Document
from harava.rdf import *

import sys
from cStringIO import StringIO

class RDFImporter (Worker):
  def __init__(self, session):
    self._session = session
    self._rdf = getGraph()

  def modify(self, rdf, subj, pred, obj):
    return subj, pred, obj

  def copy_metadata(self, rdf, doc, subj, seen=None):
    if seen is None:
      seen = set()
    seen.add(subj)
    for pred, obj in rdf.predicate_objects(subj):
      triple = self.modify(rdf, subj, pred, obj)
      if not triple: continue
      subj, pred, obj = triple
      doc.setMetadataTriple(subj, pred, obj)
      if (isinstance(obj, URIRef) or isinstance(obj, BNode)) and obj not in seen: # copy recursively
        self.copy_metadata(rdf, doc, obj, seen)
    for prefix, uri in rdf.namespaces():
      doc.setMetadataNamespace(prefix, uri)

  def process(self, rdfdoc):
    rdf = getGraph()
    data = StringIO(rdfdoc.getData())
    success = False
    for format in RDF_FORMATS:
      try:
        rdf.parse(data, format=format)
        success = True
        break
      except:
        data.seek(0)

    if success:
#      print >>sys.stderr, "%d triples found." % len(rdf)
      self._rdf += rdf
      # copy namespace prefixes as well
      for prefix, uri in rdf.namespaces():
        self._rdf.namespace_manager.bind(prefix, uri)
    else:
      print >>sys.stderr, "RDF parsing for %s failed." % rdfdoc
    data.close()

    return success
  
  def finish(self):

    for rdftype in RECOGNIZED_RDF_TYPES:
      for pub in self._rdf.subjects(RDF.type, rdftype):
        # if run for a single URL, only process that one
        url = self._session.getUrl()
        if url and URIRef(url) != pub: continue

        doc = Document(self._session, "" + pub)
        
        self.copy_metadata(self._rdf, doc, pub)
      
        doc.setCompleted('import')
        self._session.schedule(doc)
    del self._rdf
